home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / wwbbs31_source.lha / WWBBS / Library / config_lib.c < prev    next >
C/C++ Source or Header  |  1995-06-27  |  51KB  |  1,331 lines

  1. #include "wwbbs.h"
  2. #include "config.h"
  3.  
  4. struct Node *GetConfigNode(BYTE *path,BYTE *name,LONG accessmode)
  5.     {
  6.         struct List *list=NULL;
  7.         struct Node *ret=NULL;
  8.         BOOL error=FALSE;
  9.         list=&ConfigList;
  10.         ObtainSemaphoreShared(&ConfigSemaphore);
  11.         if(path && strlen(path))
  12.             {
  13.                 char buff[256],*p,*q;
  14.                 p=path;
  15.                 while(!error && p)
  16.                     {
  17.                         if(q=strchr(p,'/'))
  18.                             {
  19.                                 strncpy(buff,p,q-p);
  20.                                 buff[q-p]=NULL;
  21.                                 p=q+1;
  22.                             }
  23.                         else
  24.                             {
  25.                                 strcpy(buff,p);
  26.                                 p=NULL;
  27.                             }
  28.                         if(list)
  29.                             {
  30.                                 struct Node *node=NULL;
  31.                                 if(node=FindName(list,buff))
  32.                                     {
  33.                                         ObtainSemaphoreShared(&(((struct ConfigNode *) node)->cn_Semaphore));
  34.                                         list=((struct ConfigNode *) node)->cn_Child;
  35.                                         ret=node;
  36.                                     }
  37.                                 else
  38.                                     error=TRUE;
  39.                             }
  40.                         else
  41.                             error=TRUE;
  42.                     }
  43.             }
  44.         if(!error)
  45.             {
  46.                 if(name && strlen(name))
  47.                     {
  48.                         struct Node *node=NULL;
  49.                         if(node=FindName(list,name))
  50.                             {
  51.                                 switch(accessmode)
  52.                                     {
  53.                                         case EXCLUSIVE_LOCK:
  54.                                             ObtainSemaphore(&(((struct ConfigNode *) node)->cn_Semaphore));
  55.                                             break;
  56.                                         case SHARED_LOCK:
  57.                                         default:
  58.                                             ObtainSemaphoreShared(&(((struct ConfigNode *) node)->cn_Semaphore));
  59.                                             break;
  60.                                     }
  61.                                 ret=node;
  62.                             }
  63.                         else
  64.                             error=TRUE;
  65.                     }
  66.                 else
  67.                     error=TRUE;
  68.             }
  69.         if(error)
  70.             {
  71.                 struct Node *node=NULL;
  72.                 node=ret;
  73.                 while(node)
  74.                     {
  75.                         ReleaseSemaphore(&(((struct ConfigNode *) node)->cn_Semaphore));
  76.                         node=((struct ConfigNode *) node)->cn_Parent;
  77.                     }
  78.                 ReleaseSemaphore(&ConfigSemaphore);
  79.                 ret=NULL;
  80.             }
  81.         return(ret);
  82.     }
  83.  
  84. void FreeConfigNode(struct Node *node)
  85.     {
  86.         struct Node *wn;
  87.         wn=node;
  88.         while(wn)
  89.             {
  90.                 ReleaseSemaphore(&(((struct ConfigNode *) wn)->cn_Semaphore));
  91.                 wn=((struct ConfigNode *) wn)->cn_Parent;
  92.             }
  93.         ReleaseSemaphore(&ConfigSemaphore);
  94.     }
  95.  
  96. ULONG GetConfigFields(struct Node *node,struct TagItem *tags_orig)
  97.     {
  98.         ULONG ret=0;
  99.         struct TagItem *tags;
  100.         Tag *tags_filter=NULL;
  101.         if(tags=CloneTagItems(tags_orig))
  102.             {
  103.                 switch(((struct ConfigNode *) node)->cn_Type)
  104.                     {
  105.                         case CFGTYP_AccessGroup:
  106.                             tags_filter=accessgroup_tags;
  107.                             break;
  108.                         case CFGTYP_Archiver:
  109.                             tags_filter=archiver_tags;
  110.                             break;
  111.                         case CFGTYP_Editor:
  112.                             tags_filter=editor_tags;
  113.                             break;
  114.                         case CFGTYP_FileBase:
  115.                             if(AttemptSemaphoreShared(&FileGroupSemaphore))
  116.                                 tags_filter=filebase_tags;
  117.                             break;
  118.                         case CFGTYP_Menu:
  119.                             tags_filter=menu_tags;
  120.                             break;
  121.                         case CFGTYP_MessageBase:
  122.                             tags_filter=messagebase_tags;
  123.                             break;
  124.                         case CFGTYP_News:
  125.                             tags_filter=news_tags;
  126.                             break;
  127.                         case CFGTYP_Node:
  128.                             tags_filter=node_tags;
  129.                             break;
  130.                         case CFGTYP_Protocol:
  131.                             tags_filter=protocol_tags;
  132.                             break;
  133.                         case CFGTYP_System:
  134.                             tags_filter=system_tags;
  135.                             break;
  136.                     }
  137.                 if(tags_filter)
  138.                     {
  139.                         if(FilterTagItems(tags,tags_filter,TAGFILTER_AND))
  140.                             {
  141.                                 struct TagItem *tstate,*tag;
  142.                                 APTR data;
  143.                                 tstate=tags;
  144.                                 while(tag=NextTagItem(&tstate))
  145.                                     {
  146.                                         data=(APTR) tag->ti_Data;
  147.                                         switch(((struct ConfigNode *) node)->cn_Type)
  148.                                             {
  149.                                                 case CFGTYP_AccessGroup:
  150.                                                     switch(tag->ti_Tag)
  151.                                                         {
  152.                                                             case AGTAG_AccessLevel:
  153.                                                                 *((UBYTE *) data)=((struct AccessGroupNode *) node)->agn_AccessLevel;
  154.                                                                 break;
  155.                                                             case AGTAG_SessionTimeLimit:
  156.                                                                 *((UWORD *) data)=((struct AccessGroupNode *) node)->agn_SessionTimeLimit;
  157.                                                                 break;
  158.                                                             case AGTAG_InactivityTimeLimit:
  159.                                                                 *((UWORD *) data)=((struct AccessGroupNode *) node)->agn_InactivityTimeLimit;
  160.                                                                 break;
  161.                                                             case AGTAG_RatioByte:
  162.                                                                 *((UBYTE *) data)=((struct AccessGroupNode *) node)->agn_RatioByte;
  163.                                                                 break;
  164.                                                             case AGTAG_RatioFile:
  165.                                                                 *((UBYTE *) data)=((struct AccessGroupNode *) node)->agn_RatioFile;
  166.                                                                 break;
  167.                                                             case AGTAG_Days:
  168.                                                                 *((ULONG *) data)=((struct AccessGroupNode *) node)->agn_Days;
  169.                                                                 break;
  170.                                                         }
  171.                                                     break;
  172.                                                 case CFGTYP_Archiver:
  173.                                                     switch(tag->ti_Tag)
  174.                                                         {
  175.                                                             case ARCTAG_Extension:
  176.                                                                 strcpy((STRPTR) data,((struct ArchiverNode *) node)->an_Extension);
  177.                                                                 break;
  178.                                                             case ARCTAG_AddCommand:
  179.                                                                 strcpy((STRPTR) data,((struct ArchiverNode *) node)->an_AddCommand);
  180.                                                                 break;
  181.                                                             case ARCTAG_ExtractCommand:
  182.                                                                 strcpy((STRPTR) data,((struct ArchiverNode *) node)->an_ExtractCommand);
  183.                                                                 break;
  184.                                                             case ARCTAG_ViewCommand:
  185.                                                                 strcpy((STRPTR) data,((struct ArchiverNode *) node)->an_ViewCommand);
  186.                                                                 break;
  187.                                                         }
  188.                                                     break;
  189.                                                 case CFGTYP_Editor:
  190.                                                     switch(tag->ti_Tag)
  191.                                                         {
  192.                                                             case EDTAG_Type:
  193.                                                                 *((UBYTE *) data)=((struct EditorNode *) node)->en_Type;
  194.                                                                 break;
  195.                                                             case EDTAG_Command:
  196.                                                                 strcpy((STRPTR) data,((struct EditorNode *) node)->en_Command);
  197.                                                                 break;
  198.                                                             case EDTAG_Stack:
  199.                                                                 *((ULONG *) data)=((struct EditorNode *) node)->en_Stack;
  200.                                                                 break;
  201.                                                         }
  202.                                                     break;
  203.                                                 case CFGTYP_FileBase:
  204.                                                     switch(tag->ti_Tag)
  205.                                                         {
  206.                                                             case FBTAG_AccessRange:
  207.                                                                 strcpy((STRPTR) data,((struct FileBaseNode *) node)->fbn_AccessRange);
  208.                                                                 break;
  209.                                                             case FBTAG_Group:
  210.                                                                 strcpy((STRPTR) data,((struct FileBaseNode *) node)->fbn_Group);
  211.                                                                 break;
  212.                                                             case FBTAG_Directory:
  213.                                                                 strcpy((STRPTR) data,((struct FileBaseNode *) node)->fbn_Directory);
  214.                                                                 break;
  215.                                                             case FBTAG_DiskSpaceRequired:
  216.                                                                 *((ULONG *) data)=((struct FileBaseNode *) node)->fbn_DiskSpaceRequired;
  217.                                                                 break;
  218.                                                             case FBTAG_Days:
  219.                                                                 *((ULONG *) data)=((struct FileBaseNode *) node)->fbn_Days;
  220.                                                                 break;
  221.                                                             case FBTAG_ReadOnly:
  222.                                                                 *((BOOL *) data)=(((struct FileBaseNode *) node)->fbn_Flags & FBFLG_ReadOnly) ? TRUE : FALSE;
  223.                                                                 break;
  224.                                                             case FBTAG_AutoJoin:
  225.                                                                 *((BOOL *) data)=(((struct FileBaseNode *) node)->fbn_Flags & FBFLG_AutoJoin) ? TRUE : FALSE;
  226.                                                                 break;
  227.                                                         }
  228.                                                     break;
  229.                                                 case CFGTYP_Menu:
  230.                                                     switch(tag->ti_Tag)
  231.                                                         {
  232.                                                             case MNTAG_AccessRange:
  233.                                                                 strcpy((STRPTR) data,((struct MenuNode *) node)->mn_AccessRange);
  234.                                                                 break;
  235.                                                             case MNTAG_Character:
  236.                                                                 *((BYTE *) data)=((struct MenuNode *) node)->mn_Character;
  237.                                                                 break;
  238.                                                             case MNTAG_Default:
  239.                                                                 *((BYTE *) data)=((struct MenuNode *) node)->mn_Default;
  240.                                                                 break;
  241.                                                             case MNTAG_Number:
  242.                                                                 *((BYTE *) data)=((struct MenuNode *) node)->mn_Number;
  243.                                                                 break;
  244.                                                             case MNTAG_Prompt:
  245.                                                                 if(((struct ConfigNode *) node)->cn_Child)
  246.                                                                     strcpy((STRPTR) data,((struct MenuNode *) node)->mn_Buffer);
  247.                                                                 else
  248.                                                                     strcpy((STRPTR) data,"");
  249.                                                                 break;
  250.                                                             case MNTAG_Command:
  251.                                                                 if(((struct ConfigNode *) node)->cn_Child)
  252.                                                                     strcpy((STRPTR) data,"");
  253.                                                                 else
  254.                                                                     strcpy((STRPTR) data,((struct MenuNode *) node)->mn_Buffer);
  255.                                                                 break;
  256.                                                         }
  257.                                                     break;
  258.                                                 case CFGTYP_MessageBase:
  259.                                                     switch(tag->ti_Tag)
  260.                                                         {
  261.                                                             case MBTAG_AccessRange:
  262.                                                                 strcpy((STRPTR) data,((struct MessageBaseNode *) node)->mbn_AccessRange);
  263.                                                                 break;
  264.                                                             case MBTAG_Group:
  265.                                                                 strcpy((STRPTR) data,((struct MessageBaseNode *) node)->mbn_Group);
  266.                                                                 break;
  267.                                                             case MBTAG_QuoteHeader:
  268.                                                                 strcpy((STRPTR) data,((struct MessageBaseNode *) node)->mbn_QuoteHeader);
  269.                                                                 break;
  270.                                                             case MBTAG_Days:
  271.                                                                 *((ULONG *) data)=((struct MessageBaseNode *) node)->mbn_Days;
  272.                                                                 break;
  273.                                                             case MBTAG_ReadOnly:
  274.                                                                 *((BOOL *) data)=(((struct MessageBaseNode *) node)->mbn_Flags & MBFLG_ReadOnly) ? TRUE : FALSE;
  275.                                                                 break;
  276.                                                             case MBTAG_AutoJoin:
  277.                                                                 *((BOOL *) data)=(((struct MessageBaseNode *) node)->mbn_Flags & MBFLG_AutoJoin) ? TRUE : FALSE;
  278.                                                                 break;
  279.                                                         }
  280.                                                     break;
  281.                                                 case CFGTYP_News:
  282.                                                     switch(tag->ti_Tag)
  283.                                                         {
  284.                                                             case NWSTAG_AccessRange:
  285.                                                                 strcpy((STRPTR) data,((struct NewsNode *) node)->nn_AccessRange);
  286.                                                                 break;
  287.                                                             case NWSTAG_File:
  288.                                                                 strcpy((STRPTR) data,((struct NewsNode *) node)->nn_File);
  289.                                                                 break;
  290.                                                         }
  291.                                                     break;
  292.                                                 case CFGTYP_Node:
  293.                                                     switch(tag->ti_Tag)
  294.                                                         {
  295.                                                             case NDTAG_AccessRange:
  296.                                                                 strcpy((STRPTR) data,((struct NodeNode *) node)->nn_AccessRange);
  297.                                                                 break;
  298.                                                             case NDTAG_Type:
  299.                                                                 *((UBYTE *) data)=((struct NodeNode *) node)->nn_Type;
  300.                                                                 break;
  301.                                                             case NDTAG_Device:
  302.                                                                 strcpy((STRPTR) data,((struct NodeNode *) node)->nn_Device);
  303.                                                                 break;
  304.                                                             case NDTAG_Unit:
  305.                                                                 *((ULONG *) data)=((struct NodeNode *) node)->nn_Unit;
  306.                                                                 break;
  307.                                                             case NDTAG_BufferSize:
  308.                                                                 *((ULONG *) data)=((struct NodeNode *) node)->nn_BufferSize;
  309.                                                                 break;
  310.                                                             case NDTAG_Baud:
  311.                                                                 *((ULONG *) data)=((struct NodeNode *) node)->nn_Baud;
  312.                                                                 break;
  313.                                                             case NDTAG_Handshaking:
  314.                                                                 *((BOOL *) data)=(((struct NodeNode *) node)->nn_Flags & NDFLG_Handshaking) ? TRUE : FALSE;
  315.                                                                 break;
  316.                                                             case NDTAG_AutoBaud:
  317.                                                                 *((BOOL *) data)=(((struct NodeNode *) node)->nn_Flags & NDFLG_AutoBaud) ? TRUE : FALSE;
  318.                                                                 break;
  319.                                                             case NDTAG_FrontEnd:
  320.                                                                 *((BOOL *) data)=(((struct NodeNode *) node)->nn_Flags & NDFLG_FrontEnd) ? TRUE : FALSE;
  321.                                                                 break;
  322.                                                             case NDTAG_Command:
  323.                                                                 strcpy((STRPTR) data,((struct NodeNode *) node)->nn_Command);
  324.                                                                 break;
  325.                                                         }
  326.                                                     break;
  327.                                                 case CFGTYP_Protocol:
  328.                                                     switch(tag->ti_Tag)
  329.                                                         {
  330.                                                             case PRTAG_SendCommand:
  331.                                                                 strcpy((STRPTR) data,((struct ProtocolNode *) node)->pn_SendCommand);
  332.                                                                 break;
  333.                                                             case PRTAG_ReceiveCommand:
  334.                                                                 strcpy((STRPTR) data,((struct ProtocolNode *) node)->pn_ReceiveCommand);
  335.                                                                 break;
  336.                                                             case PRTAG_Batch:
  337.                                                                 *((BOOL *) data)=(((struct ProtocolNode *) node)->pn_Flags & PRFLG_Batch) ? TRUE : FALSE;
  338.                                                                 break;
  339.                                                             case PRTAG_Bidirectional:
  340.                                                                 *((BOOL *) data)=(((struct ProtocolNode *) node)->pn_Flags & PRFLG_Bidirectional) ? TRUE : FALSE;
  341.                                                                 break;
  342.                                                         }
  343.                                                     break;
  344.                                                 case CFGTYP_System:
  345.                                                     switch(tag->ti_Tag)
  346.                                                         {
  347.                                                             case SYSTAG_InputColor:
  348.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_InputColor);
  349.                                                                 break;
  350.                                                             case SYSTAG_HeaderColor:
  351.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_HeaderColor);
  352.                                                                 break;
  353.                                                             case SYSTAG_OutputColor:
  354.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_OutputColor);
  355.                                                                 break;
  356.                                                             case SYSTAG_PromptColor:
  357.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_PromptColor);
  358.                                                                 break;
  359.                                                             case SYSTAG_SystemColor:
  360.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_SystemColor);
  361.                                                                 break;
  362.                                                             case SYSTAG_OnlyRealNames:
  363.                                                                 *((BOOL *) data)=(((struct SystemNode *) node)->sn_Flags & SYSFLG_OnlyRealNames) ? TRUE : FALSE;
  364.                                                                 break;
  365.                                                             case SYSTAG_FileIDDizExtractor:
  366.                                                                 strcpy((STRPTR) data,((struct SystemNode *) node)->sn_FileIDDizExtractor);
  367.                                                                 break;
  368.                                                         }
  369.                                                     break;
  370.                                             }
  371.                                         ret++;
  372.                                     }
  373.                             }
  374.                         switch(((struct ConfigNode *) node)->cn_Type)
  375.                             {
  376.                                 case CFGTYP_FileBase:
  377.                                     ReleaseSemaphore(&FileGroupSemaphore);
  378.                                     break;
  379.                             }
  380.                     }
  381.                 FreeTagItems(tags);
  382.             }
  383.         return(ret);
  384.     }
  385.  
  386. ULONG SetConfigFields(struct Node *node,struct TagItem *tags_orig)
  387.     {
  388.         ULONG ret=0,retminus=0;
  389.         struct TagItem *tags;
  390.         Tag *tags_filter=NULL;
  391.         if(tags=CloneTagItems(tags_orig))
  392.             {
  393.                 switch(((struct ConfigNode *) node)->cn_Type)
  394.                     {
  395.                         case CFGTYP_AccessGroup:
  396.                             tags_filter=accessgroup_tags;
  397.                             break;
  398.                         case CFGTYP_Archiver:
  399.                             tags_filter=archiver_tags;
  400.                             break;
  401.                         case CFGTYP_Editor:
  402.                             tags_filter=editor_tags;
  403.                             break;
  404.                         case CFGTYP_FileBase:
  405.                             tags_filter=filebase_tags;
  406.                             break;
  407.                         case CFGTYP_Menu:
  408.                             tags_filter=menu_tags;
  409.                             break;
  410.                         case CFGTYP_MessageBase:
  411.                             tags_filter=messagebase_tags;
  412.                             break;
  413.                         case CFGTYP_News:
  414.                             tags_filter=news_tags;
  415.                             break;
  416.                         case CFGTYP_Node:
  417.                             tags_filter=node_tags;
  418.                             break;
  419.                         case CFGTYP_Protocol:
  420.                             tags_filter=protocol_tags;
  421.                             break;
  422.                         case CFGTYP_System:
  423.                             tags_filter=system_tags;
  424.                             break;
  425.                     }
  426.                 if(tags_filter)
  427.                     {
  428.                         if(FilterTagItems(tags,tags_filter,TAGFILTER_AND))
  429.                             {
  430.                                 struct TagItem *tstate,*tag;
  431.                                 APTR data;
  432.                                 tstate=tags;
  433.                                 while(tag=NextTagItem(&tstate))
  434.                                     {
  435.                                         data=(APTR) tag->ti_Data;
  436.                                         switch(((struct ConfigNode *) node)->cn_Type)
  437.                                             {
  438.                                                 case CFGTYP_AccessGroup:
  439.                                                     switch(tag->ti_Tag)
  440.                                                         {
  441.                                                             case AGTAG_AccessLevel:
  442.                                                                 ((struct AccessGroupNode *) node)->agn_AccessLevel=(UBYTE) data;
  443.                                                                 break;
  444.                                                             case AGTAG_SessionTimeLimit:
  445.                                                                 ((struct AccessGroupNode *) node)->agn_SessionTimeLimit=(UWORD) data;
  446.                                                                 break;
  447.                                                             case AGTAG_InactivityTimeLimit:
  448.                                                                 ((struct AccessGroupNode *) node)->agn_InactivityTimeLimit=(UWORD) data;
  449.                                                                 break;
  450.                                                             case AGTAG_RatioByte:
  451.                                                                 ((struct AccessGroupNode *) node)->agn_RatioByte=(UBYTE) data;
  452.                                                                 break;
  453.                                                             case AGTAG_RatioFile:
  454.                                                                 ((struct AccessGroupNode *) node)->agn_RatioFile=(UBYTE) data;
  455.                                                                 break;
  456.                                                             case AGTAG_Days:
  457.                                                                 ((struct AccessGroupNode *) node)->agn_Days=(ULONG) data;
  458.                                                                 break;
  459.                                                         }
  460.                                                     break;
  461.                                                 case CFGTYP_Archiver:
  462.                                                     switch(tag->ti_Tag)
  463.                                                         {
  464.                                                             case ARCTAG_Extension:
  465.                                                                 if(data && strlen((STRPTR) data)<=3)
  466.                                                                     strcpy(((struct ArchiverNode *) node)->an_Extension,(STRPTR) data);
  467.                                                                 else
  468.                                                                     retminus++;
  469.                                                                 break;
  470.                                                             case ARCTAG_AddCommand:
  471.                                                                 if(data && strlen((STRPTR) data)<=255)
  472.                                                                     strcpy(((struct ArchiverNode *) node)->an_AddCommand,(STRPTR) data);
  473.                                                                 else
  474.                                                                     retminus++;
  475.                                                                 break;
  476.                                                             case ARCTAG_ExtractCommand:
  477.                                                                 if(data && strlen((STRPTR) data)<=255)
  478.                                                                     strcpy(((struct ArchiverNode *) node)->an_ExtractCommand,(STRPTR) data);
  479.                                                                 else
  480.                                                                     retminus++;
  481.                                                                 break;
  482.                                                             case ARCTAG_ViewCommand:
  483.                                                                 if(data && strlen((STRPTR) data)<=255)
  484.                                                                     strcpy(((struct ArchiverNode *) node)->an_ViewCommand,(STRPTR) data);
  485.                                                                 else
  486.                                                                     retminus++;
  487.                                                                 break;
  488.                                                         }
  489.                                                     break;
  490.                                                 case CFGTYP_Editor:
  491.                                                     switch(tag->ti_Tag)
  492.                                                         {
  493.                                                             case EDTAG_Type:
  494.                                                                 ((struct EditorNode *) node)->en_Type=(UBYTE) data;
  495.                                                                 break;
  496.                                                             case EDTAG_Command:
  497.                                                                 if(data && strlen((STRPTR) data)<=255)
  498.                                                                     strcpy(((struct EditorNode *) node)->en_Command,(STRPTR) data);
  499.                                                                 else
  500.                                                                     retminus++;
  501.                                                                 break;
  502.                                                             case EDTAG_Stack:
  503.                                                                 ((struct EditorNode *) node)->en_Stack=(ULONG) data;
  504.                                                                 break;
  505.                                                         }
  506.                                                     break;
  507.                                                 case CFGTYP_FileBase:
  508.                                                     switch(tag->ti_Tag)
  509.                                                         {
  510.                                                             case FBTAG_AccessRange:
  511.                                                                 if(data && strlen((STRPTR) data)<=20)
  512.                                                                     strcpy(((struct FileBaseNode *) node)->fbn_AccessRange,(STRPTR) data);
  513.                                                                 else
  514.                                                                     retminus++;
  515.                                                                 break;
  516.                                                             case FBTAG_Group:
  517.                                                                 if(data && strlen((STRPTR) data)<=40)
  518.                                                                     strcpy(((struct FileBaseNode *) node)->fbn_Group,(STRPTR) data);
  519.                                                                 else
  520.                                                                     retminus++;
  521.                                                                 break;
  522.                                                             case FBTAG_Directory:
  523.                                                                 if(data && strlen((STRPTR) data)<=255)
  524.                                                                     strcpy(((struct FileBaseNode *) node)->fbn_Directory,(STRPTR) data);
  525.                                                                 else
  526.                                                                     retminus++;
  527.                                                                 break;
  528.                                                             case FBTAG_DiskSpaceRequired:
  529.                                                                 ((struct FileBaseNode *) node)->fbn_DiskSpaceRequired=(ULONG) data;
  530.                                                                 break;
  531.                                                             case FBTAG_Days:
  532.                                                                 ((struct FileBaseNode *) node)->fbn_Days=(ULONG) data;
  533.                                                                 break;
  534.                                                             case FBTAG_ReadOnly:
  535.                                                                 if((BOOL) data)
  536.                                                                     ((struct FileBaseNode *) node)->fbn_Flags|=FBFLG_ReadOnly;
  537.                                                                 else
  538.                                                                     ((struct FileBaseNode *) node)->fbn_Flags&=~FBFLG_ReadOnly;
  539.                                                                 break;
  540.                                                             case FBTAG_AutoJoin:
  541.                                                                 if((BOOL) data)
  542.                                                                     ((struct FileBaseNode *) node)->fbn_Flags|=FBFLG_AutoJoin;
  543.                                                                 else
  544.                                                                     ((struct FileBaseNode *) node)->fbn_Flags&=~FBFLG_AutoJoin;
  545.                                                                 break;
  546.                                                         }
  547.                                                     break;
  548.                                                 case CFGTYP_Menu:
  549.                                                     switch(tag->ti_Tag)
  550.                                                         {
  551.                                                             case MNTAG_AccessRange:
  552.                                                                 if(data && strlen((STRPTR) data)<=20)
  553.                                                                     strcpy(((struct MenuNode *) node)->mn_AccessRange,(STRPTR) data);
  554.                                                                 else
  555.                                                                     retminus++;
  556.                                                                 break;
  557.                                                             case MNTAG_Character:
  558.                                                                 ((struct MenuNode *) node)->mn_Character=(BYTE) data;
  559.                                                                 break;
  560.                                                             case MNTAG_Default:
  561.                                                                 ((struct MenuNode *) node)->mn_Default=(BYTE) data;
  562.                                                                 break;
  563.                                                             case MNTAG_Number:
  564.                                                                 ((struct MenuNode *) node)->mn_Number=(BYTE) data;
  565.                                                                 break;
  566.                                                             case MNTAG_Prompt:
  567.                                                                 if(((struct ConfigNode *) node)->cn_Child)
  568.                                                                     {
  569.                                                                         if(data && strlen((STRPTR) data)<=63)
  570.                                                                             strcpy(((struct MenuNode *) node)->mn_Buffer,(STRPTR) data);
  571.                                                                         else
  572.                                                                             retminus++;
  573.                                                                     }
  574.                                                                 else
  575.                                                                     retminus++;
  576.                                                                 break;
  577.                                                             case MNTAG_Command:
  578.                                                                 if(!(((struct ConfigNode *) node)->cn_Child))
  579.                                                                     {
  580.                                                                         if(data && strlen((STRPTR) data)<=63)
  581.                                                                             strcpy(((struct MenuNode *) node)->mn_Buffer,(STRPTR) data);
  582.                                                                         else
  583.                                                                             retminus++;
  584.                                                                     }
  585.                                                                 else
  586.                                                                     retminus++;
  587.                                                                 break;
  588.                                                         }
  589.                                                     break;
  590.                                                 case CFGTYP_MessageBase:
  591.                                                     switch(tag->ti_Tag)
  592.                                                         {
  593.                                                             case MBTAG_AccessRange:
  594.                                                                 if(data && strlen((STRPTR) data)<=20)
  595.                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_AccessRange,(STRPTR) data);
  596.                                                                 else
  597.                                                                     retminus++;
  598.                                                                 break;
  599.                                                             case MBTAG_Group:
  600.                                                                 if(data && strlen((STRPTR) data)<=20)
  601.                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_Group,(STRPTR) data);
  602.                                                                 else
  603.                                                                     retminus++;
  604.                                                                 break;
  605.                                                             case MBTAG_QuoteHeader:
  606.                                                                 if(data && strlen((STRPTR) data)<=80)
  607.                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_QuoteHeader,(STRPTR) data);
  608.                                                                 else
  609.                                                                     retminus++;
  610.                                                                 break;
  611.                                                             case MBTAG_Days:
  612.                                                                 ((struct MessageBaseNode *) node)->mbn_Days=(ULONG) data;
  613.                                                                 break;
  614.                                                             case MBTAG_ReadOnly:
  615.                                                                 if((BOOL) data)
  616.                                                                     ((struct MessageBaseNode *) node)->mbn_Flags|=MBFLG_ReadOnly;
  617.                                                                 else
  618.                                                                     ((struct MessageBaseNode *) node)->mbn_Flags&=~MBFLG_ReadOnly;
  619.                                                                 break;
  620.                                                             case MBTAG_AutoJoin:
  621.                                                                 if((BOOL) data)
  622.                                                                     ((struct MessageBaseNode *) node)->mbn_Flags|=MBFLG_AutoJoin;
  623.                                                                 else
  624.                                                                     ((struct MessageBaseNode *) node)->mbn_Flags&=~MBFLG_AutoJoin;
  625.                                                                 break;
  626.                                                         }
  627.                                                     break;
  628.                                                 case CFGTYP_News:
  629.                                                     switch(tag->ti_Tag)
  630.                                                         {
  631.                                                             case NWSTAG_AccessRange:
  632.                                                                 if(data && strlen((STRPTR) data)<=20)
  633.                                                                     strcpy(((struct NewsNode *) node)->nn_AccessRange,(STRPTR) data);
  634.                                                                 else
  635.                                                                     retminus++;
  636.                                                                 break;
  637.                                                             case NWSTAG_File:
  638.                                                                 if(data && strlen((STRPTR) data)<=255)
  639.                                                                     strcpy(((struct NewsNode *) node)->nn_File,(STRPTR) data);
  640.                                                                 else
  641.                                                                     retminus++;
  642.                                                                 break;
  643.                                                         }
  644.                                                     break;
  645.                                                 case CFGTYP_Node:
  646.                                                     switch(tag->ti_Tag)
  647.                                                         {
  648.                                                             case NDTAG_AccessRange:
  649.                                                                 if(data && strlen((STRPTR) data)<=20)
  650.                                                                     strcpy(((struct NodeNode *) node)->nn_AccessRange,(STRPTR) data);
  651.                                                                 else
  652.                                                                     retminus++;
  653.                                                                 break;
  654.                                                             case NDTAG_Type:
  655.                                                                 ((struct NodeNode *) node)->nn_Type=(UBYTE) data;
  656.                                                                 break;
  657.                                                             case NDTAG_Device:
  658.                                                                 if(data && strlen((STRPTR) data)<=32)
  659.                                                                     strcpy(((struct NodeNode *) node)->nn_Device,(STRPTR) data);
  660.                                                                 else
  661.                                                                     retminus++;
  662.                                                                 break;
  663.                                                             case NDTAG_Unit:
  664.                                                                 ((struct NodeNode *) node)->nn_Unit=(ULONG) data;
  665.                                                                 break;
  666.                                                             case NDTAG_BufferSize:
  667.                                                                 ((struct NodeNode *) node)->nn_BufferSize=(ULONG) data;
  668.                                                                 break;
  669.                                                             case NDTAG_Baud:
  670.                                                                 ((struct NodeNode *) node)->nn_Baud=(ULONG) data;
  671.                                                                 break;
  672.                                                             case NDTAG_Handshaking:
  673.                                                                 if((BOOL) data)
  674.                                                                     ((struct NodeNode *) node)->nn_Flags|=NDFLG_Handshaking;
  675.                                                                 else
  676.                                                                     ((struct NodeNode *) node)->nn_Flags&=~NDFLG_Handshaking;
  677.                                                                 break;
  678.                                                             case NDTAG_AutoBaud:
  679.                                                                 if((BOOL) data)
  680.                                                                     ((struct NodeNode *) node)->nn_Flags|=NDFLG_AutoBaud;
  681.                                                                 else
  682.                                                                     ((struct NodeNode *) node)->nn_Flags&=~NDFLG_AutoBaud;
  683.                                                                 break;
  684.                                                             case NDTAG_FrontEnd:
  685.                                                                 if((BOOL) data)
  686.                                                                     ((struct NodeNode *) node)->nn_Flags|=NDFLG_FrontEnd;
  687.                                                                 else
  688.                                                                     ((struct NodeNode *) node)->nn_Flags&=~NDFLG_FrontEnd;
  689.                                                                 break;
  690.                                                             case NDTAG_Command:
  691.                                                                 if(data && strlen((STRPTR) data)<=255)
  692.                                                                     strcpy(((struct NodeNode *) node)->nn_Command,(STRPTR) data);
  693.                                                                 else
  694.                                                                     retminus++;
  695.                                                                 break;
  696.                                                         }
  697.                                                     break;
  698.                                                 case CFGTYP_Protocol:
  699.                                                     switch(tag->ti_Tag)
  700.                                                         {
  701.                                                             case PRTAG_SendCommand:
  702.                                                                 if(data && strlen((STRPTR) data)<=255)
  703.                                                                     strcpy(((struct ProtocolNode *) node)->pn_SendCommand,(STRPTR) data);
  704.                                                                 else
  705.                                                                     retminus++;
  706.                                                                 break;
  707.                                                             case PRTAG_ReceiveCommand:
  708.                                                                 if(data && strlen((STRPTR) data)<=255)
  709.                                                                     strcpy(((struct ProtocolNode *) node)->pn_ReceiveCommand,(STRPTR) data);
  710.                                                                 else
  711.                                                                     retminus++;
  712.                                                                 break;
  713.                                                             case PRTAG_Batch:
  714.                                                                 if((BOOL) data)
  715.                                                                     ((struct ProtocolNode *) node)->pn_Flags|=PRFLG_Batch;
  716.                                                                 else
  717.                                                                     ((struct ProtocolNode *) node)->pn_Flags&=~PRFLG_Batch;
  718.                                                                 break;
  719.                                                             case PRTAG_Bidirectional:
  720.                                                                 if((BOOL) data)
  721.                                                                     ((struct ProtocolNode *) node)->pn_Flags|=PRFLG_Bidirectional;
  722.                                                                 else
  723.                                                                     ((struct ProtocolNode *) node)->pn_Flags&=~PRFLG_Bidirectional;
  724.                                                                 break;
  725.                                                         }
  726.                                                     break;
  727.                                                 case CFGTYP_System:
  728.                                                     switch(tag->ti_Tag)
  729.                                                         {
  730.                                                             case SYSTAG_InputColor:
  731.                                                                 if(data && strlen((STRPTR) data)<=80)
  732.                                                                     strcpy(((struct SystemNode *) node)->sn_InputColor,(STRPTR) data);
  733.                                                                 else
  734.                                                                     retminus++;
  735.                                                                 break;
  736.                                                             case SYSTAG_HeaderColor:
  737.                                                                 if(data && strlen((STRPTR) data)<=80)
  738.                                                                     strcpy(((struct SystemNode *) node)->sn_HeaderColor,(STRPTR) data);
  739.                                                                 else
  740.                                                                     retminus++;
  741.                                                                 break;
  742.                                                             case SYSTAG_OutputColor:
  743.                                                                 if(data && strlen((STRPTR) data)<=80)
  744.                                                                     strcpy(((struct SystemNode *) node)->sn_OutputColor,(STRPTR) data);
  745.                                                                 else
  746.                                                                     retminus++;
  747.                                                                 break;
  748.                                                             case SYSTAG_PromptColor:
  749.                                                                 if(data && strlen((STRPTR) data)<=80)
  750.                                                                     strcpy(((struct SystemNode *) node)->sn_PromptColor,(STRPTR) data);
  751.                                                                 else
  752.                                                                     retminus++;
  753.                                                                 break;
  754.                                                             case SYSTAG_SystemColor:
  755.                                                                 if(data && strlen((STRPTR) data)<=80)
  756.                                                                     strcpy(((struct SystemNode *) node)->sn_SystemColor,(STRPTR) data);
  757.                                                                 else
  758.                                                                     retminus++;
  759.                                                                 break;
  760.                                                             case SYSTAG_OnlyRealNames:
  761.                                                                 if((BOOL) data)
  762.                                                                     ((struct SystemNode *) node)->sn_Flags|=SYSFLG_OnlyRealNames;
  763.                                                                 else
  764.                                                                     ((struct SystemNode *) node)->sn_Flags&=~SYSFLG_OnlyRealNames;
  765.                                                                 break;
  766.                                                             case SYSTAG_FileIDDizExtractor:
  767.                                                                 if(data && strlen((STRPTR) data)<=80)
  768.                                                                     strcpy(((struct SystemNode *) node)->sn_FileIDDizExtractor,(STRPTR) data);
  769.                                                                 else
  770.                                                                     retminus++;
  771.                                                                 break;
  772.                                                         }
  773.                                                     break;
  774.                                             }
  775.                                         ret++;
  776.                                     }
  777.                             }
  778.                     }
  779.                 FreeTagItems(tags);
  780.             }
  781.         ret-=retminus;
  782.         return(ret);
  783.     }
  784.  
  785. void LoadConfig(BYTE *configfile)
  786.     {
  787.         BPTR fh;
  788.         ObtainSemaphore(&ConfigSemaphore);
  789.         if(fh=Open(configfile,MODE_OLDFILE))
  790.             {
  791.                 BOOL kg=TRUE;
  792.                 LONG cmd;
  793.                 struct List *list=NULL;
  794.                 struct Node *node=NULL,*parent=NULL;
  795.                 list=&ConfigList;
  796.                 while(kg)
  797.                     {
  798.                         cmd=FGetC(fh);
  799.                         switch(cmd)
  800.                             {
  801.                                 case -1: /* EOF */
  802.                                     kg=FALSE;
  803.                                     break;
  804.                                 case CFGCMD_Begin:
  805.                                     {
  806.                                         ULONG size=0;
  807.                                         LONG typ;
  808.                                         typ=FGetC(fh);
  809.                                         switch(typ)
  810.                                             {
  811.                                                 case -1: /* EOF */
  812.                                                     kg=FALSE;
  813.                                                     break;
  814.                                                 case CFGTYP_Config:
  815.                                                     size=sizeof(struct ConfigNode);
  816.                                                     break;
  817.                                                 case CFGTYP_AccessGroup:
  818.                                                     size=sizeof(struct AccessGroupNode);
  819.                                                     break;
  820.                                                 case CFGTYP_Archiver:
  821.                                                     size=sizeof(struct ArchiverNode);
  822.                                                     break;
  823.                                                 case DUMMY_DoorVariable:
  824.                                                     size=sizeof(struct ConfigNode);
  825.                                                     break;
  826.                                                 case CFGTYP_Editor:
  827.                                                     size=sizeof(struct EditorNode);
  828.                                                     break;
  829.                                                 case CFGTYP_FileBase:
  830.                                                     size=sizeof(struct FileBaseNode);
  831.                                                     break;
  832.                                                 case CFGTYP_Menu:
  833.                                                     size=sizeof(struct MenuNode);
  834.                                                     break;
  835.                                                 case CFGTYP_MessageBase:
  836.                                                     size=sizeof(struct MessageBaseNode);
  837.                                                     break;
  838.                                                 case CFGTYP_News:
  839.                                                     size=sizeof(struct NewsNode);
  840.                                                     break;
  841.                                                 case CFGTYP_Node:
  842.                                                     size=sizeof(struct NodeNode);
  843.                                                     break;
  844.                                                 case CFGTYP_Protocol:
  845.                                                     size=sizeof(struct ProtocolNode);
  846.                                                     break;
  847.                                                 case CFGTYP_System:
  848.                                                     size=sizeof(struct SystemNode);
  849.                                                     break;
  850.                                             }
  851.                                         if(size)
  852.                                             {
  853.                                                 if(node=AllocVec(size,MEMF_CLEAR))
  854.                                                     {
  855.                                                         node->ln_Name=((struct ConfigNode *) node)->cn_Name;
  856.                                                         InitSemaphore(&(((struct ConfigNode *) node)->cn_Semaphore));
  857.                                                         ((struct ConfigNode *) node)->cn_Type=typ;
  858.                                                         ((struct ConfigNode *) node)->cn_Parent=parent;
  859.                                                     }
  860.                                                 else
  861.                                                     kg=FALSE;
  862.                                             }
  863.                                     }
  864.                                     break;
  865.                                 case CFGCMD_Child:
  866.                                     if(node)
  867.                                         {
  868.                                             if(((struct ConfigNode *) node)->cn_Child=AllocVec(sizeof(struct List),MEMF_CLEAR))
  869.                                                 {
  870.                                                     NewList(((struct ConfigNode *) node)->cn_Child);
  871.                                                     list=((struct ConfigNode *) node)->cn_Child;
  872.                                                     parent=node;
  873.                                                 }
  874.                                             else
  875.                                                 kg=FALSE;
  876.                                         }
  877.                                     break;
  878.                                 case CFGCMD_End:
  879.                                     if(node)
  880.                                         AddTail(list,node);
  881.                                     break;
  882.                                 case CFGCMD_Field:
  883.                                     if(node)
  884.                                         {
  885.                                             LONG field;
  886.                                             UWORD size;
  887.                                             if( ((field=FGetC(fh))!=-1) && (FRead(fh,&size,sizeof(UWORD),1)) )
  888.                                                 {
  889.                                                     APTR data;
  890.                                                     if(data=AllocVec(size,MEMF_CLEAR))
  891.                                                         {
  892.                                                             if(FRead(fh,data,size,1))
  893.                                                                 {
  894.                                                                     if(field==CFGFLD_Name)
  895.                                                                         strcpy(node->ln_Name,(STRPTR) data);
  896.                                                                     else
  897.                                                                         {
  898.                                                                             switch(((struct ConfigNode *) node)->cn_Type)
  899.                                                                                 {
  900.                                                                                     case CFGTYP_AccessGroup:
  901.                                                                                         switch(field)
  902.                                                                                             {
  903.                                                                                                 case AGFLD_AccessLevel:
  904.                                                                                                     ((struct AccessGroupNode *) node)->agn_AccessLevel=*((UBYTE *) data);
  905.                                                                                                     break;
  906.                                                                                                 case AGFLD_SessionTimeLimit:
  907.                                                                                                     ((struct AccessGroupNode *) node)->agn_SessionTimeLimit=*((UWORD *) data);
  908.                                                                                                     break;
  909.                                                                                                 case AGFLD_InactivityTimeLimit:
  910.                                                                                                     ((struct AccessGroupNode *) node)->agn_InactivityTimeLimit=*((UWORD *) data);
  911.                                                                                                     break;
  912.                                                                                                 case AGFLD_RatioByte:
  913.                                                                                                     ((struct AccessGroupNode *) node)->agn_RatioByte=*((UBYTE *) data);
  914.                                                                                                     break;
  915.                                                                                                 case AGFLD_RatioFile:
  916.                                                                                                     ((struct AccessGroupNode *) node)->agn_RatioFile=*((UBYTE *) data);
  917.                                                                                                     break;
  918.                                                                                                 case AGFLD_Days:
  919.                                                                                                     ((struct AccessGroupNode *) node)->agn_Days=*((ULONG *) data);
  920.                                                                                                     break;
  921.                                                                                             }
  922.                                                                                         break;
  923.                                                                                     case CFGTYP_Archiver:
  924.                                                                                         switch(field)
  925.                                                                                             {
  926.                                                                                                 case ARCFLD_Extension:
  927.                                                                                                     strcpy(((struct ArchiverNode *) node)->an_Extension,(STRPTR) data);
  928.                                                                                                     break;
  929.                                                                                                 case ARCFLD_AddCommand:
  930.                                                                                                     strcpy(((struct ArchiverNode *) node)->an_AddCommand,(STRPTR) data);
  931.                                                                                                     break;
  932.                                                                                                 case ARCFLD_ExtractCommand:
  933.                                                                                                     strcpy(((struct ArchiverNode *) node)->an_ExtractCommand,(STRPTR) data);
  934.                                                                                                     break;
  935.                                                                                                 case ARCFLD_ViewCommand:
  936.                                                                                                     strcpy(((struct ArchiverNode *) node)->an_ViewCommand,(STRPTR) data);
  937.                                                                                                     break;
  938.                                                                                             }
  939.                                                                                         break;
  940.                                                                                     case CFGTYP_Editor:
  941.                                                                                         switch(field)
  942.                                                                                             {
  943.                                                                                                 case EDFLD_Type:
  944.                                                                                                     ((struct EditorNode *) node)->en_Type=*((UBYTE *) data);
  945.                                                                                                     break;
  946.                                                                                                 case EDFLD_Command:
  947.                                                                                                     strcpy(((struct EditorNode *) node)->en_Command,(STRPTR) data);
  948.                                                                                                     break;
  949.                                                                                                 case EDFLD_Stack:
  950.                                                                                                     ((struct EditorNode *) node)->en_Stack=*((ULONG *) data);
  951.                                                                                                     break;
  952.                                                                                             }
  953.                                                                                         break;
  954.                                                                                     case CFGTYP_FileBase:
  955.                                                                                         switch(field)
  956.                                                                                             {
  957.                                                                                                 case FBFLD_AccessRange:
  958.                                                                                                     strcpy(((struct FileBaseNode *) node)->fbn_AccessRange,(STRPTR) data);
  959.                                                                                                     break;
  960.                                                                                                 case FBFLD_Group:
  961.                                                                                                     strcpy(((struct FileBaseNode *) node)->fbn_Group,(STRPTR) data);
  962.                                                                                                     break;
  963.                                                                                                 case FBFLD_Directory:
  964.                                                                                                     strcpy(((struct FileBaseNode *) node)->fbn_Directory,(STRPTR) data);
  965.                                                                                                     break;
  966.                                                                                                 case FBFLD_DiskSpaceRequired:
  967.                                                                                                     ((struct FileBaseNode *) node)->fbn_DiskSpaceRequired=*((ULONG *) data);
  968.                                                                                                     break;
  969.                                                                                                 case FBFLD_Days:
  970.                                                                                                     ((struct FileBaseNode *) node)->fbn_Days=*((ULONG *) data);
  971.                                                                                                     break;
  972.                                                                                                 case FBFLD_Flags:
  973.                                                                                                     ((struct FileBaseNode *) node)->fbn_Flags=*((ULONG *) data);
  974.                                                                                                     break;
  975.                                                                                             }
  976.                                                                                         break;
  977.                                                                                     case CFGTYP_Menu:
  978.                                                                                         switch(field)
  979.                                                                                             {
  980.                                                                                                 case MNFLD_AccessRange:
  981.                                                                                                     strcpy(((struct MenuNode *) node)->mn_AccessRange,(STRPTR) data);
  982.                                                                                                     break;
  983.                                                                                                 case MNFLD_Character:
  984.                                                                                                     ((struct MenuNode *) node)->mn_Character=*((BYTE *) data);
  985.                                                                                                     break;
  986.                                                                                                 case MNFLD_Default:
  987.                                                                                                     ((struct MenuNode *) node)->mn_Default=*((BYTE *) data);
  988.                                                                                                     break;
  989.                                                                                                 case MNFLD_Number:
  990.                                                                                                     ((struct MenuNode *) node)->mn_Number=*((BYTE *) data);
  991.                                                                                                     break;
  992.                                                                                                 case MNFLD_Buffer:
  993.                                                                                                     strcpy(((struct MenuNode *) node)->mn_Buffer,(STRPTR) data);
  994.                                                                                                     break;
  995.                                                                                             }
  996.                                                                                         break;
  997.                                                                                     case CFGTYP_MessageBase:
  998.                                                                                         switch(field)
  999.                                                                                             {
  1000.                                                                                                 case MBFLD_AccessRange:
  1001.                                                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_AccessRange,(STRPTR) data);
  1002.                                                                                                     break;
  1003.                                                                                                 case MBFLD_Group:
  1004.                                                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_Group,(STRPTR) data);
  1005.                                                                                                     break;
  1006.                                                                                                 case MBFLD_QuoteHeader:
  1007.                                                                                                     strcpy(((struct MessageBaseNode *) node)->mbn_QuoteHeader,(STRPTR) data);
  1008.                                                                                                     break;
  1009.                                                                                                 case MBFLD_Flags:
  1010.                                                                                                     ((struct MessageBaseNode *) node)->mbn_Flags=*((ULONG *) data);
  1011.                                                                                                     break;
  1012.                                                                                                 case MBFLD_Days:
  1013.                                                                                                     ((struct MessageBaseNode *) node)->mbn_Days=*((ULONG *) data);
  1014.                                                                                                     break;
  1015.                                                                                             }
  1016.                                                                                         break;
  1017.                                                                                     case CFGTYP_News:
  1018.                                                                                         switch(field)
  1019.                                                                                             {
  1020.                                                                                                 case NWSFLD_AccessRange:
  1021.                                                                                                     strcpy(((struct NewsNode *) node)->nn_AccessRange,(STRPTR) data);
  1022.                                                                                                     break;
  1023.                                                                                                 case NWSFLD_File:
  1024.                                                                                                     strcpy(((struct NewsNode *) node)->nn_File,(STRPTR) data);
  1025.                                                                                                     break;
  1026.                                                                                             }
  1027.                                                                                         break;
  1028.                                                                                     case CFGTYP_Node:
  1029.                                                                                         switch(field)
  1030.                                                                                             {
  1031.                                                                                                 case NDFLD_AccessRange:
  1032.                                                                                                     strcpy(((struct NodeNode *) node)->nn_AccessRange,(STRPTR) data);
  1033.                                                                                                     break;
  1034.                                                                                                 case NDFLD_Type:
  1035.                                                                                                     ((struct NodeNode *) node)->nn_Type=*((UBYTE *) data);
  1036.                                                                                                     break;
  1037.                                                                                                 case NDFLD_Device:
  1038.                                                                                                     strcpy(((struct NodeNode *) node)->nn_Device,(STRPTR) data);
  1039.                                                                                                     break;
  1040.                                                                                                 case NDFLD_Unit:
  1041.                                                                                                     ((struct NodeNode *) node)->nn_Unit=*((ULONG *) data);
  1042.                                                                                                     break;
  1043.                                                                                                 case NDFLD_BufferSize:
  1044.                                                                                                     ((struct NodeNode *) node)->nn_BufferSize=*((ULONG *) data);
  1045.                                                                                                     break;
  1046.                                                                                                 case NDFLD_Baud:
  1047.                                                                                                     ((struct NodeNode *) node)->nn_Baud=*((ULONG *) data);
  1048.                                                                                                     break;
  1049.                                                                                                 case NDFLD_Flags:
  1050.                                                                                                     ((struct NodeNode *) node)->nn_Flags=*((ULONG *) data);
  1051.                                                                                                     break;
  1052.                                                                                                 case NDFLD_Command:
  1053.                                                                                                     strcpy(((struct NodeNode *) node)->nn_Command,(STRPTR) data);
  1054.                                                                                                     break;
  1055.                                                                                             }
  1056.                                                                                         break;
  1057.                                                                                     case CFGTYP_Protocol:
  1058.                                                                                         switch(field)
  1059.                                                                                             {
  1060.                                                                                                 case PRFLD_SendCommand:
  1061.                                                                                                     strcpy(((struct ProtocolNode *) node)->pn_SendCommand,(STRPTR) data);
  1062.                                                                                                     break;
  1063.                                                                                                 case PRFLD_ReceiveCommand:
  1064.                                                                                                     strcpy(((struct ProtocolNode *) node)->pn_ReceiveCommand,(STRPTR) data);
  1065.                                                                                                     break;
  1066.                                                                                                 case PRFLD_Flags:
  1067.                                                                                                     ((struct ProtocolNode *) node)->pn_Flags=*((ULONG *) data);
  1068.                                                                                                     break;
  1069.                                                                                             }
  1070.                                                                                         break;
  1071.                                                                                     case CFGTYP_System:
  1072.                                                                                         switch(field)
  1073.                                                                                             {
  1074.                                                                                                 case SYSFLD_InputColor:
  1075.                                                                                                     strcpy(((struct SystemNode *) node)->sn_InputColor,(STRPTR) data);
  1076.                                                                                                     break;
  1077.                                                                                                 case SYSFLD_HeaderColor:
  1078.                                                                                                     strcpy(((struct SystemNode *) node)->sn_HeaderColor,(STRPTR) data);
  1079.                                                                                                     break;
  1080.                                                                                                 case SYSFLD_OutputColor:
  1081.                                                                                                     strcpy(((struct SystemNode *) node)->sn_OutputColor,(STRPTR) data);
  1082.                                                                                                     break;
  1083.                                                                                                 case SYSFLD_PromptColor:
  1084.                                                                                                     strcpy(((struct SystemNode *) node)->sn_PromptColor,(STRPTR) data);
  1085.                                                                                                     break;
  1086.                                                                                                 case SYSFLD_SystemColor:
  1087.                                                                                                     strcpy(((struct SystemNode *) node)->sn_SystemColor,(STRPTR) data);
  1088.                                                                                                     break;
  1089.                                                                                                 case SYSFLD_Flags:
  1090.                                                                                                     ((struct SystemNode *) node)->sn_Flags=*((ULONG *) data);
  1091.                                                                                                     break;
  1092.                                                                                                 case SYSFLD_FileIDDizExtractor:
  1093.                                                                                                     strcpy(((struct SystemNode *) node)->sn_FileIDDizExtractor,(STRPTR) data);
  1094.                                                                                                     break;
  1095.                                                                                             }
  1096.                                                                                         break;
  1097.                                                                                 }
  1098.                                                                         }
  1099.                                                                 }
  1100.                                                             else
  1101.                                                                 kg=FALSE;
  1102.                                                             FreeVec(data);
  1103.                                                         }
  1104.                                                     else
  1105.                                                         kg=FALSE;
  1106.                                                 }
  1107.                                             else
  1108.                                                 kg=FALSE;
  1109.                                         }
  1110.                                     break;
  1111.                                 case CFGCMD_Parent:
  1112.                                     if(parent)
  1113.                                         {
  1114.                                             parent=((struct ConfigNode *) parent)->cn_Parent;
  1115.                                             if(parent)
  1116.                                                 list=((struct ConfigNode *) parent)->cn_Child;
  1117.                                             else
  1118.                                                 list=&ConfigList;
  1119.                                         }
  1120.                                     break;
  1121.                             }
  1122.                     }
  1123.                 Close(fh);
  1124.                 ReleaseSemaphore(&ConfigSemaphore);
  1125.             }
  1126.         else
  1127.             {
  1128.                 ReleaseSemaphore(&ConfigSemaphore);
  1129.                 AddConfigTags(
  1130.                     CFGTAG_Name,"AccessGroups",
  1131.                     CFGTAG_Type,CFGTYP_Config,
  1132.                     CFGTAG_DontSave,TRUE,
  1133.                     TAG_END);
  1134.                 AddConfigTags(
  1135.                     CFGTAG_Name,"Archivers",
  1136.                     CFGTAG_Type,CFGTYP_Config,
  1137.                     CFGTAG_DontSave,TRUE,
  1138.                     TAG_END);
  1139.                 AddConfigTags(
  1140.                     CFGTAG_Name,"Editors",
  1141.                     CFGTAG_Type,CFGTYP_Config,
  1142.                     CFGTAG_DontSave,TRUE,
  1143.                     TAG_END);
  1144.                 AddConfigTags(
  1145.                     CFGTAG_Name,"FileBases",
  1146.                     CFGTAG_Type,CFGTYP_Config,
  1147.                     CFGTAG_DontSave,TRUE,
  1148.                     TAG_END);
  1149.                 AddConfigTags(
  1150.                     CFGTAG_Name,"Menus",
  1151.                     CFGTAG_Type,CFGTYP_Config,
  1152.                     CFGTAG_DontSave,TRUE,
  1153.                     TAG_END);
  1154.                 AddConfigTags(
  1155.                     CFGTAG_Name,"MessageBases",
  1156.                     CFGTAG_Type,CFGTYP_Config,
  1157.                     CFGTAG_DontSave,TRUE,
  1158.                     TAG_END);
  1159.                 AddConfigTags(
  1160.                     CFGTAG_Name,"News",
  1161.                     CFGTAG_Type,CFGTYP_Config,
  1162.                     CFGTAG_DontSave,TRUE,
  1163.                     TAG_END);
  1164.                 AddConfigTags(
  1165.                     CFGTAG_Name,"Nodes",
  1166.                     CFGTAG_Type,CFGTYP_Config,
  1167.                     CFGTAG_DontSave,TRUE,
  1168.                     TAG_END);
  1169.                 AddConfigTags(
  1170.                     CFGTAG_Name,"Protocols",
  1171.                     CFGTAG_Type,CFGTYP_Config,
  1172.                     CFGTAG_DontSave,TRUE,
  1173.                     TAG_END);
  1174.                 AddConfigTags(
  1175.                     CFGTAG_Name,"System",
  1176.                     CFGTAG_Type,CFGTYP_System,
  1177.                     CFGTAG_DontSave,TRUE,
  1178.                     TAG_END);
  1179.             }
  1180.     }
  1181.  
  1182. void SaveConfig(BYTE *configfile)
  1183.     {
  1184.         BPTR fh;
  1185.         ObtainSemaphore(&ConfigSemaphore);
  1186.         if(fh=Open(configfile,MODE_NEWFILE))
  1187.             {
  1188.                 SaveConfigList(fh,&ConfigList);
  1189.                 Close(fh);
  1190.             }
  1191.         ReleaseSemaphore(&ConfigSemaphore);
  1192.     }
  1193.  
  1194. void SaveConfigList(BPTR fh,struct List *list)
  1195.     {
  1196.         struct Node *node;
  1197.         for(node=list->lh_Head;node->ln_Succ;node=node->ln_Succ)
  1198.             {
  1199.                 switch(((struct ConfigNode *) node)->cn_Type)
  1200.                     {
  1201.                         case DUMMY_DoorVariable:
  1202.                             break;
  1203.                         default:
  1204.                             SaveConfigNode(fh,node);
  1205.                     }
  1206.                 if(((struct ConfigNode *) node)->cn_Child)
  1207.                     {
  1208.                         FPutC(fh,CFGCMD_Child);
  1209.                         SaveConfigList(fh,((struct ConfigNode *) node)->cn_Child);
  1210.                         FPutC(fh,CFGCMD_Parent);
  1211.                     }
  1212.             }
  1213.     }
  1214.  
  1215. void SaveConfigNode(BPTR fh,struct Node *node)
  1216.     {
  1217.         /* Begin Node */
  1218.         FPutC(fh,CFGCMD_Begin);
  1219.  
  1220.         /* Node Type */
  1221.         FPutC(fh,(LONG) ((struct ConfigNode *) node)->cn_Type);
  1222.  
  1223.         /* Name Field */
  1224.         SaveConfigField(fh,CFGFLD_Name,strlen(node->ln_Name)+1,node->ln_Name);
  1225.  
  1226.         switch(((struct ConfigNode *) node)->cn_Type)
  1227.             {
  1228.                 case CFGTYP_AccessGroup:
  1229.                     SaveConfigField(fh,AGFLD_AccessLevel,sizeof(UBYTE),&(((struct AccessGroupNode *) node)->agn_AccessLevel));
  1230.                     SaveConfigField(fh,AGFLD_SessionTimeLimit,sizeof(UWORD),&(((struct AccessGroupNode *) node)->agn_SessionTimeLimit));
  1231.                     SaveConfigField(fh,AGFLD_InactivityTimeLimit,sizeof(UWORD),&(((struct AccessGroupNode *) node)->agn_InactivityTimeLimit));
  1232.                     SaveConfigField(fh,AGFLD_RatioByte,sizeof(UBYTE),&(((struct AccessGroupNode *) node)->agn_RatioByte));
  1233.                     SaveConfigField(fh,AGFLD_RatioFile,sizeof(UBYTE),&(((struct AccessGroupNode *) node)->agn_RatioFile));
  1234.                     SaveConfigField(fh,AGFLD_Days,sizeof(ULONG),&(((struct AccessGroupNode *) node)->agn_Days));
  1235.                     break;
  1236.                 case CFGTYP_Archiver:
  1237.                     SaveConfigField(fh,ARCFLD_Extension,strlen(((struct ArchiverNode *) node)->an_Extension)+1,((struct ArchiverNode *) node)->an_Extension);
  1238.                     SaveConfigField(fh,ARCFLD_AddCommand,strlen(((struct ArchiverNode *) node)->an_AddCommand)+1,((struct ArchiverNode *) node)->an_AddCommand);
  1239.                     SaveConfigField(fh,ARCFLD_ExtractCommand,strlen(((struct ArchiverNode *) node)->an_ExtractCommand)+1,((struct ArchiverNode *) node)->an_ExtractCommand);
  1240.                     SaveConfigField(fh,ARCFLD_ViewCommand,strlen(((struct ArchiverNode *) node)->an_ViewCommand)+1,((struct ArchiverNode *) node)->an_ViewCommand);
  1241.                     break;
  1242.                 case CFGTYP_Editor:
  1243.                     SaveConfigField(fh,EDFLD_Type,sizeof(UBYTE),&(((struct EditorNode *) node)->en_Type));
  1244.                     SaveConfigField(fh,EDFLD_Command,strlen(((struct EditorNode *) node)->en_Command)+1,((struct EditorNode *) node)->en_Command);
  1245.                     SaveConfigField(fh,EDFLD_Stack,sizeof(ULONG),&(((struct EditorNode *) node)->en_Stack));
  1246.                     break;
  1247.                 case CFGTYP_FileBase:
  1248.                     SaveConfigField(fh,FBFLD_AccessRange,strlen(((struct FileBaseNode *) node)->fbn_AccessRange)+1,((struct FileBaseNode *) node)->fbn_AccessRange);
  1249.                     SaveConfigField(fh,FBFLD_Group,strlen(((struct FileBaseNode *) node)->fbn_Group)+1,((struct FileBaseNode *) node)->fbn_Group);
  1250.                     SaveConfigField(fh,FBFLD_Directory,strlen(((struct FileBaseNode *) node)->fbn_Directory)+1,((struct FileBaseNode *) node)->fbn_Directory);
  1251.                     SaveConfigField(fh,FBFLD_DiskSpaceRequired,sizeof(ULONG),&(((struct FileBaseNode *) node)->fbn_DiskSpaceRequired));
  1252.                     SaveConfigField(fh,FBFLD_Days,sizeof(ULONG),&(((struct FileBaseNode *) node)->fbn_Days));
  1253.                     SaveConfigField(fh,FBFLD_Flags,sizeof(ULONG),&(((struct FileBaseNode *) node)->fbn_Flags));
  1254.                     break;
  1255.                 case CFGTYP_Menu:
  1256.                     SaveConfigField(fh,MNFLD_AccessRange,strlen(((struct MenuNode *) node)->mn_AccessRange)+1,((struct MenuNode *) node)->mn_AccessRange);
  1257.                     SaveConfigField(fh,MNFLD_Character,sizeof(BYTE),&(((struct MenuNode *) node)->mn_Character));
  1258.                     SaveConfigField(fh,MNFLD_Default,sizeof(BYTE),&(((struct MenuNode *) node)->mn_Default));
  1259.                     SaveConfigField(fh,MNFLD_Number,sizeof(BYTE),&(((struct MenuNode *) node)->mn_Number));
  1260.                     SaveConfigField(fh,MNFLD_Buffer,strlen(((struct MenuNode *) node)->mn_Buffer)+1,((struct MenuNode *) node)->mn_Buffer);
  1261.                     break;
  1262.                 case CFGTYP_MessageBase:
  1263.                     SaveConfigField(fh,MBFLD_AccessRange,strlen(((struct MessageBaseNode *) node)->mbn_AccessRange)+1,((struct MessageBaseNode *) node)->mbn_AccessRange);
  1264.                     SaveConfigField(fh,MBFLD_Group,strlen(((struct MessageBaseNode *) node)->mbn_Group)+1,((struct MessageBaseNode *) node)->mbn_Group);
  1265.                     SaveConfigField(fh,MBFLD_QuoteHeader,strlen(((struct MessageBaseNode *) node)->mbn_QuoteHeader)+1,((struct MessageBaseNode *) node)->mbn_QuoteHeader);
  1266.                     SaveConfigField(fh,MBFLD_Flags,sizeof(ULONG),&(((struct MessageBaseNode *) node)->mbn_Flags));
  1267.                     SaveConfigField(fh,MBFLD_Days,sizeof(ULONG),&(((struct MessageBaseNode *) node)->mbn_Days));
  1268.                     break;
  1269.                 case CFGTYP_News:
  1270.                     SaveConfigField(fh,NWSFLD_AccessRange,strlen(((struct NewsNode *) node)->nn_AccessRange)+1,((struct NewsNode *) node)->nn_AccessRange);
  1271.                     SaveConfigField(fh,NWSFLD_File,strlen(((struct NewsNode *) node)->nn_File)+1,((struct NewsNode *) node)->nn_File);
  1272.                     break;
  1273.                 case CFGTYP_Node:
  1274.                     SaveConfigField(fh,NDFLD_AccessRange,strlen(((struct NodeNode *) node)->nn_AccessRange)+1,((struct NodeNode *) node)->nn_AccessRange);
  1275.                     SaveConfigField(fh,NDFLD_Type,sizeof(UBYTE),&(((struct NodeNode *) node)->nn_Type));
  1276.                     SaveConfigField(fh,NDFLD_Device,strlen(((struct NodeNode *) node)->nn_Device)+1,((struct NodeNode *) node)->nn_Device);
  1277.                     SaveConfigField(fh,NDFLD_Unit,sizeof(ULONG),&(((struct NodeNode *) node)->nn_Unit));
  1278.                     SaveConfigField(fh,NDFLD_BufferSize,sizeof(ULONG),&(((struct NodeNode *) node)->nn_BufferSize));
  1279.                     SaveConfigField(fh,NDFLD_Baud,sizeof(ULONG),&(((struct NodeNode *) node)->nn_Baud));
  1280.                     SaveConfigField(fh,NDFLD_Flags,sizeof(ULONG),&(((struct NodeNode *) node)->nn_Flags));
  1281.                     SaveConfigField(fh,NDFLD_Command,strlen(((struct NodeNode *) node)->nn_Command)+1,((struct NodeNode *) node)->nn_Command);
  1282.                     break;
  1283.                 case CFGTYP_Protocol:
  1284.                     SaveConfigField(fh,PRFLD_SendCommand,strlen(((struct ProtocolNode *) node)->pn_SendCommand)+1,((struct ProtocolNode *) node)->pn_SendCommand);
  1285.                     SaveConfigField(fh,PRFLD_ReceiveCommand,strlen(((struct ProtocolNode *) node)->pn_ReceiveCommand)+1,((struct ProtocolNode *) node)->pn_ReceiveCommand);
  1286.                     SaveConfigField(fh,PRFLD_Flags,sizeof(ULONG),&(((struct ProtocolNode *) node)->pn_Flags));
  1287.                     break;
  1288.                 case CFGTYP_System:
  1289.                     SaveConfigField(fh,SYSFLD_InputColor,strlen(((struct SystemNode *) node)->sn_InputColor)+1,((struct SystemNode *) node)->sn_InputColor);
  1290.                     SaveConfigField(fh,SYSFLD_HeaderColor,strlen(((struct SystemNode *) node)->sn_HeaderColor)+1,((struct SystemNode *) node)->sn_HeaderColor);
  1291.                     SaveConfigField(fh,SYSFLD_OutputColor,strlen(((struct SystemNode *) node)->sn_OutputColor)+1,((struct SystemNode *) node)->sn_OutputColor);
  1292.                     SaveConfigField(fh,SYSFLD_PromptColor,strlen(((struct SystemNode *) node)->sn_PromptColor)+1,((struct SystemNode *) node)->sn_PromptColor);
  1293.                     SaveConfigField(fh,SYSFLD_SystemColor,strlen(((struct SystemNode *) node)->sn_SystemColor)+1,((struct SystemNode *) node)->sn_SystemColor);
  1294.                     SaveConfigField(fh,SYSFLD_Flags,sizeof(ULONG),&(((struct SystemNode *) node)->sn_Flags));
  1295.                     SaveConfigField(fh,SYSFLD_FileIDDizExtractor,strlen(((struct SystemNode *) node)->sn_FileIDDizExtractor)+1,((struct SystemNode *) node)->sn_FileIDDizExtractor);
  1296.                     break;
  1297.             }
  1298.  
  1299.         /* End Node */
  1300.         FPutC(fh,CFGCMD_End);
  1301.     }
  1302.  
  1303. void SaveConfigField(BPTR fh,LONG field,UWORD size,APTR data)
  1304.     {
  1305.         FPutC(fh,CFGCMD_Field);
  1306.         FPutC(fh,field);
  1307.         FWrite(fh,&size,sizeof(UWORD),1);
  1308.         FWrite(fh,data,(ULONG) size,1);
  1309.     }
  1310.  
  1311. void UnLoadConfig()
  1312.     {
  1313.         ObtainSemaphore(&ConfigSemaphore);
  1314.         UnLoadConfigList(&ConfigList);
  1315.         ReleaseSemaphore(&ConfigSemaphore);
  1316.     }
  1317.  
  1318. void UnLoadConfigList(struct List *list)
  1319.     {
  1320.         struct Node *node;
  1321.         while(node=RemHead(list))
  1322.             {
  1323.                 if(((struct ConfigNode *) node)->cn_Child)
  1324.                     {
  1325.                         UnLoadConfigList(((struct ConfigNode *) node)->cn_Child);
  1326.                         FreeVec(((struct ConfigNode *) node)->cn_Child);
  1327.                     }
  1328.                 FreeVec(node);
  1329.             }
  1330.     }
  1331.